#include <Windows.h> // Include the Win32 API
#include <tchar.h> // Include support for UNICODE

#if defined( DEBUG ) || defined( _DEBUG )
#include <vld.h>
#endif

#include "Game.h"
#include <time.h>



const TCHAR* g_szWINDOW_CLASS_NAME	= _T("TriQuest");	//	Window Class Name.
const TCHAR* g_szWINDOW_TITLE		= _T("TriQuest");	//	Window Title.
const int	g_nWINDOW_WIDTH			= 800;				//	Window Width.
const int	g_nWINDOW_HEIGHT		= 600;				//	Window Height.


//	Windowed or Full screen depending on project setting
#ifdef _DEBUG
const BOOL	g_bIS_WINDOWED			= TRUE;						
#else
const BOOL	g_bIS_WINDOWED			= FALSE;
#endif

// Forward Declarations:
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
void OnPaint(HWND hWnd);

// The new entry point for a Windows Program
int CALLBACK _tWinMain(
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPTSTR lpCmdLine,
  int nCmdShow
)
{
	srand(unsigned int(time(0)));
	// Step 1 - Register the Window Class
	WNDCLASSEX wcex = {};
	wcex.cbSize = sizeof(wcex);
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hInstance = hInstance;
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WindowProc; // Identify the function that will process messages.
	wcex.lpszMenuName = g_szWINDOW_TITLE;
	wcex.lpszClassName = g_szWINDOW_CLASS_NAME; // Identify this Window Class by its name.
	RegisterClassEx(&wcex);

	// AdjustWindowRect - Calculate the perfect client size

	DWORD dwWindowStyleFlags = WS_VISIBLE;

	if( g_bIS_WINDOWED == TRUE )
	{
		dwWindowStyleFlags |= WS_OVERLAPPEDWINDOW;
	}
	else
	{
		dwWindowStyleFlags |= WS_POPUP;
		ShowCursor( FALSE );				
	}

	RECT rWindow;
	rWindow.left	= 0;
	rWindow.top		= 0;
	rWindow.right	= g_nWINDOW_WIDTH;
	rWindow.bottom	= g_nWINDOW_HEIGHT;

	AdjustWindowRect( &rWindow, 
		dwWindowStyleFlags,
		FALSE );

	int nWindowWidth	= rWindow.right - rWindow.left;
	int nWindowHeight	= rWindow.bottom - rWindow.top;

	// Step 2 - Create the Main Window
	HWND hWnd = CreateWindow(wcex.lpszClassName,
							 wcex.lpszMenuName,
							 dwWindowStyleFlags,
							 CW_USEDEFAULT, CW_USEDEFAULT,
							 nWindowWidth, nWindowHeight,
							 HWND_DESKTOP,
							 NULL,
							 hInstance,
							 NULL);
	if (! hWnd)
	{
		MessageBox(HWND_DESKTOP, _T("ERROR: Failed to create the Main Window."),
					_T("Program Name"), MB_OK | MB_ICONERROR);
		return -1;
	}

	// SetWindowText - Change the Title Bar String

	//TODO: Make sure all program data is initialize at this point.

	// Step 3 - Display the Main Window
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd); // Start the WM_PAINT messages

	// Initialize Game Here
	CGame* pGame = CGame::GetInstance();
	pGame->Initialize( hWnd, hInstance, 
		g_nWINDOW_WIDTH, g_nWINDOW_HEIGHT, g_bIS_WINDOWED );

	// Step 4 - Enter the Main Message Loop (Windows Message Queue)
	MSG msg = {};
	while( true )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) == TRUE )
		{ 
			if( msg.message == WM_QUIT )
				break;

			TranslateMessage( &msg );

			DispatchMessage( &msg );
		}
		else
		{
			if( pGame->Main() == false )
				PostQuitMessage( 0 );
		}
	}

	pGame->Shutdown();
	CGame::DeleteInstance();
	pGame = nullptr;

	UnregisterClass( g_szWINDOW_CLASS_NAME, hInstance );

	return msg.wParam;
}

// Step 5 - Implement the Window Procedure
LRESULT CALLBACK WindowProc(
  HWND hWnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
	switch (uMsg)
	{
	// Window Constructor
	case WM_CREATE:
		break;

	// Window Destructor
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	// Window Output
	case WM_PAINT:
		OnPaint(hWnd);
		break;

	default:
		// Tell Windows to perform default message processing.
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}


void OnPaint(HWND hWnd)
{
	// GDI - Graphics Device Interface
	PAINTSTRUCT ps_Painter;
	HDC hdc = BeginPaint(hWnd, &ps_Painter); // Give me a Device Context



	EndPaint(hWnd, &ps_Painter);
}